package com.idanchuang.support.etcache.local;

import java.util.HashMap;
import java.util.Map;

/**
 *
 * LocalCache 的抽象实现
 *
 * @author yjy
 * Created at 2021/12/21 11:10 上午
 */
public abstract class AbstractLocalCache<K, V> implements LocalCache<K, V> {

    private final LocalCacheConfig config;

    protected AbstractLocalCache(LocalCacheConfig config) {
        this.config = config;
    }

    /**
     * 构造一级缓存key对象
     * @param key 原始key
     * @return LocalKey
     */
    protected LocalKey<K> buildKey(K key) {
        return buildKey(config.getPressureChecker().isPressure(), key);
    }

    /**
     * 构造一级缓存key对象
     * @param isPressure 是否压测
     * @param key 原始key
     * @return LocalKey
     */
    protected LocalKey<K> buildKey(boolean isPressure, K key) {
        return new LocalKey<>(isPressure ? 1 : 0, key);
    }

    @Override
    public V get(K key) {
        LocalKey<K> localKey = buildKey(key);
        return doGet(localKey);
    }

    /**
     * 读取缓存
     * @param localKey ..
     * @return ..
     */
    protected abstract V doGet(LocalKey<K> localKey);

    @Override
    public Map<K, V> getAll(Iterable<K> keys) {
        boolean isPressure = config.getPressureChecker().isPressure();
        Map<K, V> resMap = new HashMap<>();
        for (K k : keys) {
            LocalKey<K> localKey = buildKey(isPressure, k);
            resMap.put(k, doGet(localKey));
        }
        return resMap;
    }

    @Override
    public void set(K key, V value) {
        LocalKey<K> localKey = buildKey(key);
        doSet(localKey, value);
    }

    /**
     * 设置缓存
     * @param localKey ..
     * @param value ..
     */
    protected abstract void doSet(LocalKey<K> localKey, V value);

    @Override
    public void setAll(Map<K, V> map) {
        boolean isPressure = config.getPressureChecker().isPressure();
        map.forEach((k, v) -> {
            LocalKey<K> localKey = buildKey(isPressure, k);
            doSet(localKey, v);
        });
    }

    @Override
    public void remove(K key) {
        LocalKey<K> localKey = buildKey(key);
        doRemove(localKey);
    }

    /**
     * 移除缓存
     * @param localKey ..
     */
    protected abstract void doRemove(LocalKey<K> localKey);

    @Override
    public void removeAll(Iterable<K> keys) {
        boolean isPressure = config.getPressureChecker().isPressure();
        for (K k : keys) {
            LocalKey<K> localKey = buildKey(isPressure, k);
            doRemove(localKey);
        }
    }

    @Override
    public void removeAccurate(LocalKey<K> localKey) {
        doRemove(localKey);
    }

    @Override
    public LocalCacheConfig getConfig() {
        return config;
    }
}
